<?php
/**
 * 注册db到容器
 *
 * @version    0.1.1
 * @author     Dingwu
 */

namespace App\Providers;

use Frado\Container\Container;
use Frado\Container\ServiceProviderInterface;
use Frado\DB\Connection;
use Frado\Cache\Redis as RedisCache;


class DbServiceProvider implements ServiceProviderInterface
{

    /**
     * 注册服务到容器
     * @param Container $app
     */
    public function register(Container $app)
    {
        $config = $app['config']->get('database', []);

        $this->registerDbs($app, $config['mysql']);

        $this->registerRedis($app, $config['redis']);
    }

    private function registerDbs($app, $config)
    {
        $app['db'] = function ($app) use ($config) {
            $default = $config['default'] ?? [];
            $this->parseDsn($default);
            $connect = new Connection($default);
            $connect->open();
            return $connect;
        };

        $dbConfig = $config['db'] ?? [];
        foreach ($dbConfig as $name => $item) {
            $item = array_merge($config['default'], $item);
            $app["db.{$name}"] = function ($app) use ($item) {
                $this->parseDsn($item);
                $connect = new Connection($item);
                $connect->open();
                return $connect;
            };
        }
    }

    private function parseDsn(&$config, $placeholder = '{database}')
    {
        if (strpos($config['dsn'], $placeholder) !== false) {
            $config['dsn'] = str_replace($placeholder, $config['database'], $config['dsn']);
        }
        if (isset($config['database'])) {
            unset($config['database']);
        }
    }

    private function registerRedis($app, $config)
    {
        $redis = function ($ip, $port, $password, $options = []) {
            return new RedisCache($ip, $port, $password, $options);
        };
        foreach ($config as $name => $item) {
            $app["redis.{$name}"] = function () use ($item, $redis) {
                if (count($item) > 1) {
                    return $redis;
                }

                return new RedisCache(...$item[0]);
            };
        }
    }

}